<script setup lang="ts">
defineOptions({
  name: "imageInfo"
});

import { ref, computed, inject, getCurrentInstance, nextTick, onUnmounted } from "vue";
import leftArrow from "@/assets/svg/common/left.svg?component";
import rightArrow from "@/assets/svg/common/right.svg?component";
import filePreview from "./filePreview.vue";
import { queryFileList } from "@/api/modules/fab";
import { fileTypes } from "../utils";
import ReTextTooltip from "@/components/ReTextTooltip";

const { proxy }: any = getCurrentInstance();

const loading = inject<any>("loading", ref<boolean>(false));
const index = ref<number>(0);
const transition_from_width = ref<string>("80px");
const transition_to_width = ref<string>("80px");
let loopTimer = null;
const delay = 5000;

const props = withDefaults(defineProps<{ ids: Array<string> }>(), { ids: () => [] });
const files = ref<Array<any>>([]);
const filesLen = computed(() => files.value?.length);

const downFile = () => {
  const f = files.value[index.value];
  if (!f) return;
  const { id = "", fileName = "", moduleName = "", originalName = "" } = f;
  const params = {
    id,
    fileName,
    moduleName
  };
  proxy.download("post", "/sharing/api/v1/file/download", params, originalName);
};

const step = (n: number) => {
  if (files.value?.length && files.value.length > 1) {
    const len = files.value.length;
    if (n < 0) {
      transition_from_width.value = "80px";
      transition_to_width.value = "-80px";
      if (index.value < 1) {
        index.value = len - 1;
      } else {
        index.value--;
      }
    } else if (n > 0) {
      transition_from_width.value = "-80px";
      transition_to_width.value = "80px";
      if (index.value + 1 < len) {
        index.value++;
      } else {
        index.value = 0;
      }
    }
  }
};

const queryFileListFn = async (ids: Array<string>): Promise<Array<any>> => {
  const res = await queryFileList({ ids });
  if (!res?.length) return;
  res.reverse();
  return res.map(item => {
    const { fileUrl } = item;
    if (fileUrl) {
      const f = fileUrl.split(".")?.pop() || "";
      if (!f) return item;
      const t = fileTypes.get(f.toLowerCase());
      item["type"] = t?.type || "";
      item["fileType"] = t?.fileType || "";
      item["filePath"] = t?.path || "";
    }
    return item;
  });
};

const init = async () => {
  files.value.splice(0);
  if (!props.ids?.length) return;
  files.value = await queryFileListFn(props.ids);
  await nextTick();
  startLoop();
};

const startLoop = () => {
  if (files.value?.length < 2) return;
  clearLoop();
  loopTimer = setInterval(() => {
    step(1);
  }, delay);
};

const clearLoop = () => {
  clearInterval(loopTimer);
  loopTimer = null;
};

onUnmounted(() => {
  clearLoop();
});

defineExpose({
  init,
  files
});
</script>

<template>
  <div v-loading="loading" class="detail-image">
    <div class="detail-image-content">
      <div class="icon images-content-left" :class="{ disabled: filesLen < 2 }" @click="step(-1)">
        <leftArrow class="icon-item" onselectstart="return false" />
      </div>
      <div class="images-content-center" @mouseover="clearLoop" @mouseleave="startLoop">
        <transition name="fab-detail-images" mode="out-in">
          <div
            v-if="files[index]?.fileType === 'image'"
            :key="files[index]?.id"
            class="image-content"
            :style="{ backgroundImage: `url(${files[index]?.fileUrl})` }"
          />
          <div v-else-if="files[index]?.fileType === 'file'" :key="files[index].id" class="file-content">
            <div class="file-content-title">
              <ReTextTooltip :content="files[index].originalName" :style="{ textAlign: 'center' }" />
            </div>
            <px-icon class="file-content-icon" :size="80" @click="downFile">
              <component :is="fileTypes.get(files[index].filePath)?.icon || fileTypes.get('default').icon" />
            </px-icon>
          </div>
        </transition>
      </div>
      <div class="icon images-content-right" :class="{ disabled: filesLen < 2 }" @click="step(1)">
        <rightArrow class="icon-item" onselectstart="return false" />
      </div>
    </div>
    <div class="detail-image-preview">
      <filePreview v-model="index" :files="files" />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.detail-image {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  padding-top: 16px;

  .detail-image-title {
    width: 100%;
  }

  .detail-image-content {
    display: flex;
    flex: 1;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    position: relative;
    .icon {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      z-index: 99;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 46px;
      height: 46px;
      cursor: pointer;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 0 10px #bababa;
      .icon-item {
        width: 30px;
        color: #3b82f6;
      }

      &:hover {
        box-shadow: 0 0 16px #aaa;
      }
    }
    .images-content-left {
      left: 0;
    }
    .images-content-right {
      right: 0;
    }

    .disabled {
      cursor: not-allowed;

      .icon-item {
        color: #ccc;
      }

      &:hover {
        box-shadow: none;
      }
    }

    .images-content-center {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;

      .fab-detail-images-enter-active,
      .fab-detail-images-leave-active {
        transition: all 0.4s ease;
      }

      .fab-detail-images-enter-from {
        opacity: 0;
        transform: translateX(v-bind(transition_to_width));
      }

      .fab-detail-images-leave-to {
        opacity: 0;
        transform: translateX(v-bind(transition_from_width));
      }

      .image-content {
        width: 100%;
        height: 100%;
        background-repeat: no-repeat;
        background-position: center;
        background-size: contain;
      }

      .file-content {
        display: flex;
        flex-direction: column;
        gap: 24px;
        align-items: center;
        justify-content: center;

        .file-content-title {
          width: 100%;
        }

        .file-content-icon {
          &:hover {
            cursor: pointer;
            transition: all 0.2s;
            transform: scale(1.1);
          }
        }
      }
    }
  }

  .detail-image-preview {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
